home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / tnos / tnos100s / asy.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-30  |  7.3 KB  |  316 lines

  1. /* Generic serial line interface routines
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4.  /* Mods by G1EMM */
  5. #include <stdio.h>
  6. #include "global.h"
  7. #include "config.h"
  8. #include "proc.h"
  9. #include "iface.h"
  10. #include "netuser.h"
  11. #include "slhc.h"
  12. #include "i8250.h"
  13. #include "asy.h"
  14. #include "ax25.h"
  15. #include "kiss.h"
  16. #include "pktdrvr.h"
  17. #include "ppp.h"
  18. #include "slip.h"
  19. #include "nrs.h"
  20. #include "commands.h"
  21. #include "mbuf.h"
  22.  
  23. static int asy_detach __ARGS((struct iface *ifp));
  24.  
  25.  
  26. /* Attach a serial interface to the system
  27.  * argv[0]: hardware type, must be "asy"
  28.  * argv[1]: I/O address, e.g., "0x3f8"
  29.  * argv[2]: vector, e.g., "4"
  30.  * argv[3]: mode, may be:
  31.  *        "slip" (point-to-point SLIP)
  32.  *        "ax25" (AX.25 frame format in SLIP for raw TNC)
  33.  *        "nrs" (NET/ROM format serial protocol)
  34.  *        "ppp" (Point-to-Point Protocol, RFC1171, RFC1172)
  35.  * argv[4]: interface label, e.g., "sl0"
  36.  * argv[5]: receiver ring buffer size in bytes
  37.  * argv[6]: maximum transmission unit, bytes
  38.  * argv[7]: interface speed, e.g, "9600"
  39.  * argv[8]: optional flags,
  40.  *        'v' for Van Jacobson TCP header compression (SLIP only,
  41.  *            use ppp command for VJ compression with PPP);
  42.  *      'f' for forced use of the 16550 fifo's - WG7J
  43.  *      'nn' to set 16550 trigger level - WG7J
  44.  */
  45. int
  46. asy_attach(argc,argv,p)
  47. int argc;
  48. char *argv[];
  49. void *p;
  50. {
  51.     register struct iface *ifp;
  52.     struct asy *asyp;
  53.     char *ifn;
  54.     int dev;
  55.     int xdev;
  56.     int trigchar = -1;
  57.     char monitor = FALSE;
  58.     int triglevel = 0;
  59.     int force = 0;
  60.     char *cp;
  61. #if    defined(SLIP) || defined(AX25)
  62.     struct slip *sp;
  63. #endif
  64. #ifdef    NRS
  65.     struct nrs *np;
  66. #endif
  67.  
  68.     if(if_lookup(argv[4]) != NULLIF){
  69.         tprintf(Existingiface,argv[4]);
  70.         return -1;
  71.     }
  72.     /* Find unused asy control block */
  73.     for(dev=0;dev < ASY_MAX;dev++){
  74.         asyp = &Asy[dev];
  75.         if(asyp->iface == NULLIF)
  76.             break;
  77.     }
  78.     if(dev >= ASY_MAX){
  79.         tprintf("Too many async controllers\n");
  80.         return -1;
  81.     }
  82.  
  83.     /* Create interface structure and fill in details */
  84.     ifp = (struct iface *)callocw(1,sizeof(struct iface));
  85.     ifp->addr = Ip_addr;
  86.     ifp->name = strdup(argv[4]);
  87.     ifp->mtu = atoi(argv[6]);
  88.     ifp->dev = dev;
  89.     ifp->stop = asy_detach;
  90.  
  91.     /*Check for forced 16550 fifo usage - WG7J */
  92.     if((argc > 8) && ((cp = strchr(argv[8],'f')) != NULLCHAR)) {
  93.         force = 1;
  94.         if((triglevel = atoi(++cp)) == 0)   /* is there an additional arg ? */
  95.             if(argc > 9)
  96.                 triglevel = atoi(argv[9]);
  97.     }
  98.  
  99.  
  100. #ifdef    SLIP
  101.     if(stricmp(argv[3],"SLIP") == 0) {
  102.         for(xdev = 0;xdev < SLIP_MAX;xdev++){
  103.             sp = &Slip[xdev];
  104.             if(sp->iface == NULLIF)
  105.                 break;
  106.         }
  107.         if(xdev >= SLIP_MAX) {
  108.             tprintf("Too many slip devices\n");
  109.             free(ifp->name);
  110.             free((char *)ifp);
  111.             return -1;
  112.         }
  113.         setencap(ifp,"SLIP");
  114.         ifp->ioctl = asy_ioctl;
  115.         ifp->raw = slip_raw;
  116.         ifp->show = slip_status;
  117.         ifp->flags = 0;
  118.         ifp->xdev = xdev;
  119.  
  120.         sp->iface = ifp;
  121.         sp->send = asy_send;
  122.         sp->get = get_asy;
  123.         sp->type = CL_SERIAL_LINE;
  124.         trigchar = FR_END;
  125. #ifdef VJCOMPRESS
  126.         if((argc > 8) && (strchr(argv[8],'v') != NULLCHAR)) {
  127.             sp->escaped |= SLIP_VJCOMPR;
  128.             sp->slcomp = slhc_init(16,16);
  129.         }
  130. #else
  131.         sp->slcomp = NULL;
  132. #endif    /* VJCOMPRESS */
  133.         ifp->rxproc = newproc( ifn = if_name( ifp, " rx" ),
  134.             256,asy_rx,xdev,NULL,NULL,0);
  135.         free(ifn);
  136.     } else
  137. #endif
  138. #ifdef    AX25
  139.     if(stricmp(argv[3],"AX25") == 0) {
  140.         /* Set up a SLIP link to use AX.25 */
  141.         for(xdev = 0;xdev < SLIP_MAX;xdev++){
  142.             sp = &Slip[xdev];
  143.             if(sp->iface == NULLIF)
  144.                 break;
  145.         }
  146.         if(xdev >= SLIP_MAX) {
  147.             tprintf("Too many ax25 devices\n");
  148.             free(ifp->name);
  149.             free((char *)ifp);
  150.             return -1;
  151.         }
  152.         setencap(ifp,"AX25");
  153.         ifp->ioctl = kiss_ioctl;
  154.         ifp->raw = kiss_raw;
  155.         ifp->show = slip_status;
  156.         ifp->port = 0;            /* G1EMM */
  157.         if(ifp->hwaddr == NULLCHAR)
  158.             ifp->hwaddr = mallocw(AXALEN);
  159.         memcpy(ifp->hwaddr,Mycall,AXALEN);
  160.         if(ifp->ipcall == NULLCHAR)
  161.             ifp->ipcall = mallocw(AXALEN);
  162.         memcpy(ifp->ipcall,Mycall,AXALEN);
  163.         ifp->xdev = xdev;
  164.  
  165.         sp->iface = ifp;
  166.         sp->send = asy_send;
  167.         sp->kiss[ifp->port] = ifp;    /* G1EMM */
  168.         sp->get = get_asy;
  169.         sp->type = CL_KISS;
  170.         trigchar = FR_END;
  171.         ifp->rxproc = newproc( ifn = if_name( ifp, " rx" ),
  172.             256,asy_rx,xdev,NULL,NULL,0);
  173.         free(ifn);
  174.     } else
  175. #endif
  176. #ifdef    NRS
  177.     if(stricmp(argv[3],"NRS") == 0) {
  178.         /* Set up a net/rom serial iface */
  179.         for(xdev = 0;xdev < SLIP_MAX;xdev++){
  180.             np = &Nrs[xdev];
  181.             if(np->iface == NULLIF)
  182.                 break;
  183.         }
  184.         if(xdev >= SLIP_MAX) {
  185.             tprintf("Too many nrs devices\n");
  186.             free(ifp->name);
  187.             free((char *)ifp);
  188.             return -1;
  189.         }
  190.         /* no call supplied? */
  191.         setencap(ifp,"AX25");
  192.         ifp->ioctl = asy_ioctl;
  193.         ifp->raw = nrs_raw;
  194. /*        ifp->show = nrs_status; */
  195.         ifp->hwaddr = mallocw(AXALEN);
  196.         memcpy(ifp->hwaddr,Mycall,AXALEN);
  197.         ifp->ipcall = mallocw(AXALEN);
  198.         memcpy(ifp->ipcall,Mycall,AXALEN);
  199.         ifp->xdev = xdev;
  200.         np->iface = ifp;
  201.         np->send = asy_send;
  202.         np->get = get_asy;
  203.         trigchar = ETX;
  204.         ifp->rxproc = newproc( ifn = if_name( ifp, " nrs" ),
  205.             256,nrs_recv,xdev,NULL,NULL,0);
  206.         free(ifn);
  207.     } else
  208. #endif
  209. #ifdef    PPP
  210.     if(stricmp(argv[3],"PPP") == 0) {
  211.         /* Setup for Point-to-Point Protocol */
  212.         trigchar = HDLC_FLAG;
  213.         monitor = TRUE;
  214.         setencap(ifp,"PPP");
  215.         ifp->ioctl = asy_ioctl;
  216.         ifp->flags = FALSE;
  217.         /* Initialize parameters for various PPP phases/protocols */
  218.         if (ppp_init(ifp) != 0) {
  219.             tprintf("Cannot allocate PPP control block\n");
  220.             free(ifp->name);
  221.             free((char *)ifp);
  222.             return -1;
  223.         }
  224.     } else
  225. #endif /* PPP */
  226.     {
  227.         tprintf("Mode %s unknown for interface %s\n",
  228.             argv[3],argv[4]);
  229.         free(ifp->name);
  230.         free((char *)ifp);
  231.         return -1;
  232.     }
  233.  
  234.     /* Link in the interface */
  235.     ifp->next = Ifaces;
  236.     Ifaces = ifp;
  237.     asy_init(dev,ifp,argv[1],argv[2],(int16)atol(argv[5]),
  238.         trigchar,monitor,(int16)atol(argv[7]),force,triglevel);
  239.     return 0;
  240. }
  241.  
  242. static int
  243. asy_detach(ifp)
  244. struct iface *ifp;
  245. {
  246.     asy_stop(ifp);
  247.  
  248. #ifdef    SLIP
  249.     if(stricmp(ifp->iftype->name,"SLIP") == 0) {
  250.         Slip[ifp->xdev].iface = NULLIF;
  251. #ifdef VJCOMPRESS
  252.         slhc_free( Slip[ifp->xdev].slcomp );
  253.         Slip[ifp->xdev].slcomp = NULL;
  254. #endif    /* VJCOMPRESS */
  255.     } else
  256. #endif
  257. #ifdef    AX25
  258.     if(stricmp(ifp->iftype->name,"AX25") == 0
  259.      && Slip[ifp->xdev].iface == ifp ) {
  260.         Slip[ifp->xdev].iface = NULLIF;
  261.     } else
  262. #endif
  263. #ifdef    NRS
  264.     if(stricmp(ifp->iftype->name,"AX25") == 0
  265.      && Nrs[ifp->xdev].iface == ifp ) {
  266.         Nrs[ifp->xdev].iface = NULLIF;
  267.     } else
  268. #endif
  269. #ifdef    PPP
  270.     if(stricmp(ifp->iftype->name,"PPP") == 0) {
  271.         ppp_free(ifp);
  272.     } else
  273. #endif
  274.     {
  275.         tprintf("invalid type %s for interface %s\n",
  276.             ifp->iftype->name, ifp->name);
  277.         free(ifp->name);
  278.         free(ifp);
  279.         return -1;
  280.     }
  281.     return 0;
  282. }
  283.  
  284. /* Execute user comm command */
  285. int
  286. doasycomm(argc,argv,p)
  287. int argc;
  288. char *argv[];
  289. void *p;
  290. {
  291.     register struct iface *ifp;
  292.     register struct asy *ap;
  293.     int dev;
  294.     struct mbuf *bp;
  295.     
  296.     if((ifp = if_lookup(argv[1])) == NULLIF){
  297.         tprintf(Badinterface,argv[1]);
  298.         return 1;
  299.     }
  300.     for(dev=0,ap = Asy;dev < ASY_MAX;dev++,ap++)
  301.         if(ap->iface == ifp)
  302.             break;
  303.     if(dev == ASY_MAX){
  304.         tprintf("Interface %s not asy port\n",argv[1]);
  305.         return 1;
  306.     }
  307.  
  308.     bp = pushdown(NULLBUF,strlen(argv[2]) + 2 );
  309.     strcpy(bp->data,argv[2]);
  310.     strcat(bp->data,"\r");
  311.     bp->cnt = strlen(argv[2]) + 1;
  312.     asy_send(dev,bp);
  313.     return 0;
  314. }
  315.  
  316.